package cn.com.anypay.manager.common.utils;

import cn.com.anypay.manager.dto.wechat.WeChatUserInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信认证数据工具类
 * 用于处理存储在sys_user_auth表中的微信认证相关数据
 */
@Slf4j
public class WeChatAuthDataUtils {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 构建微信认证的extraData字段内容
     * 
     * @param weChatUserInfo 微信用户信息
     * @return JSON格式的extraData字符串
     */
    public static String buildExtraData(WeChatUserInfo weChatUserInfo) {
        try {
            Map<String, Object> extraData = new HashMap<>();
            
            // 基本信息
            extraData.put("openId", weChatUserInfo.getOpenId());
            extraData.put("unionId", weChatUserInfo.getUnionId());
            extraData.put("nickname", weChatUserInfo.getNickname());
            extraData.put("headImgUrl", weChatUserInfo.getHeadImgUrl());
            
            // 用户属性
            extraData.put("sex", weChatUserInfo.getSex());
            extraData.put("sexDesc", weChatUserInfo.getSexDesc());
            extraData.put("country", weChatUserInfo.getCountry());
            extraData.put("province", weChatUserInfo.getProvince());
            extraData.put("city", weChatUserInfo.getCity());
            extraData.put("language", weChatUserInfo.getLanguage());
            extraData.put("privilege", weChatUserInfo.getPrivilege());
            
            // 元数据
            extraData.put("lastUpdateTime", LocalDateTime.now().toString());
            extraData.put("dataVersion", "1.0");
            
            return objectMapper.writeValueAsString(extraData);
            
        } catch (JsonProcessingException e) {
            log.error("构建微信认证extraData失败: openId={}", 
                weChatUserInfo.getOpenId(), e);
            return "{}";
        }
    }

    /**
     * 解析extraData字段中的微信用户信息
     * 
     * @param extraData JSON格式的extraData字符串
     * @return 解析后的数据Map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> parseExtraData(String extraData) {
        if (!StringUtils.hasText(extraData)) {
            return new HashMap<>();
        }
        
        try {
            return objectMapper.readValue(extraData, Map.class);
        } catch (JsonProcessingException e) {
            log.error("解析微信认证extraData失败: extraData={}", extraData, e);
            return new HashMap<>();
        }
    }

    /**
     * 从extraData中提取微信OpenID
     * 
     * @param extraData JSON格式的extraData字符串
     * @return 微信OpenID
     */
    public static String extractOpenId(String extraData) {
        Map<String, Object> data = parseExtraData(extraData);
        Object openId = data.get("openId");
        return openId != null ? openId.toString() : null;
    }

    /**
     * 从extraData中提取微信昵称
     * 
     * @param extraData JSON格式的extraData字符串
     * @return 微信昵称
     */
    public static String extractNickname(String extraData) {
        Map<String, Object> data = parseExtraData(extraData);
        Object nickname = data.get("nickname");
        return nickname != null ? nickname.toString() : null;
    }

    /**
     * 从extraData中提取微信头像URL
     * 
     * @param extraData JSON格式的extraData字符串
     * @return 微信头像URL
     */
    public static String extractHeadImgUrl(String extraData) {
        Map<String, Object> data = parseExtraData(extraData);
        Object headImgUrl = data.get("headImgUrl");
        return headImgUrl != null ? headImgUrl.toString() : null;
    }

    /**
     * 从extraData中提取微信UnionID
     * 
     * @param extraData JSON格式的extraData字符串
     * @return 微信UnionID
     */
    public static String extractUnionId(String extraData) {
        Map<String, Object> data = parseExtraData(extraData);
        Object unionId = data.get("unionId");
        return unionId != null ? unionId.toString() : null;
    }

    /**
     * 更新extraData中的特定字段
     * 
     * @param originalExtraData 原始extraData
     * @param key 要更新的字段名
     * @param value 新值
     * @return 更新后的extraData字符串
     */
    public static String updateExtraDataField(String originalExtraData, String key, Object value) {
        try {
            Map<String, Object> data = parseExtraData(originalExtraData);
            data.put(key, value);
            data.put("lastUpdateTime", LocalDateTime.now().toString());
            
            return objectMapper.writeValueAsString(data);
            
        } catch (JsonProcessingException e) {
            log.error("更新微信认证extraData字段失败: key={}, value={}", key, value, e);
            return originalExtraData;
        }
    }

    /**
     * 检查extraData是否包含有效的微信信息
     * 
     * @param extraData JSON格式的extraData字符串
     * @return 是否有效
     */
    public static boolean isValidWeChatExtraData(String extraData) {
        if (!StringUtils.hasText(extraData)) {
            return false;
        }
        
        Map<String, Object> data = parseExtraData(extraData);
        String openId = extractOpenId(extraData);
        
        return StringUtils.hasText(openId) && data.containsKey("dataVersion");
    }

    /**
     * 构建用于显示的微信用户信息摘要
     * 
     * @param extraData JSON格式的extraData字符串
     * @return 用户信息摘要
     */
    public static Map<String, Object> buildUserInfoSummary(String extraData) {
        Map<String, Object> data = parseExtraData(extraData);
        Map<String, Object> summary = new HashMap<>();
        
        // 基本显示信息
        summary.put("nickname", data.get("nickname"));
        summary.put("headImgUrl", data.get("headImgUrl"));
        summary.put("sexDesc", data.get("sexDesc"));
        summary.put("location", buildLocationString(data));
        summary.put("lastUpdateTime", data.get("lastUpdateTime"));
        
        return summary;
    }

    /**
     * 构建地理位置字符串
     * 
     * @param data 解析后的extraData
     * @return 地理位置字符串
     */
    private static String buildLocationString(Map<String, Object> data) {
        StringBuilder location = new StringBuilder();
        
        Object country = data.get("country");
        Object province = data.get("province");
        Object city = data.get("city");
        
        if (country != null && StringUtils.hasText(country.toString())) {
            location.append(country.toString());
        }
        
        if (province != null && StringUtils.hasText(province.toString())) {
            if (location.length() > 0) {
                location.append(" ");
            }
            location.append(province.toString());
        }
        
        if (city != null && StringUtils.hasText(city.toString())) {
            if (location.length() > 0) {
                location.append(" ");
            }
            location.append(city.toString());
        }
        
        return location.toString();
    }

    /**
     * 脱敏处理OpenID（用于日志记录）
     * 
     * @param openId 原始OpenID
     * @return 脱敏后的OpenID
     */
    public static String maskOpenId(String openId) {
        if (!StringUtils.hasText(openId) || openId.length() < 8) {
            return "***";
        }
        
        return openId.substring(0, 4) + "***" + openId.substring(openId.length() - 4);
    }

    /**
     * 验证微信OpenID格式
     * 
     * @param openId 微信OpenID
     * @return 是否有效
     */
    public static boolean isValidOpenId(String openId) {
        return StringUtils.hasText(openId) && 
               openId.length() >= 20 && 
               openId.length() <= 32 &&
               openId.matches("^[a-zA-Z0-9_-]+$");
    }

    /**
     * 生成微信用户的默认用户名
     * 
     * @param openId 微信OpenID
     * @return 默认用户名
     */
    public static String generateDefaultUsername(String openId) {
        if (!isValidOpenId(openId)) {
            throw new IllegalArgumentException("无效的微信OpenID");
        }
        
        return "wx_" + openId;
    }

    /**
     * 从微信用户名中提取OpenID
     * 
     * @param username 微信用户名（格式：wx_openid）
     * @return OpenID，如果格式不正确返回null
     */
    public static String extractOpenIdFromUsername(String username) {
        if (!StringUtils.hasText(username) || !username.startsWith("wx_")) {
            return null;
        }
        
        String openId = username.substring(3);
        return isValidOpenId(openId) ? openId : null;
    }
}